#include "pch.h"
#include "FilterPipeConfig.h"

using namespace AutomatedSurfaceReconstruction;

bool CFilterPipeConfig::init()
{
	_ASSERTE(!m_IsReady);

	const hiveConfig::CHiveConfig* pConfig = getSubconfigAt(0);
	if (!isSubconfigValid(pConfig, std::string("FilterPipeSystem")))return false;

	const hiveConfig::CHiveConfig* pFiltersConfig = pConfig->getSubconfigAt(0);
	if (!isSubconfigValid(pFiltersConfig, std::string("Filters")))return false;
	for (int i = 0; i < pFiltersConfig->getNumSubconfigs(); i++)
	{
		const hiveConfig::CHiveConfig* pFilterConfig = pFiltersConfig->getSubconfigAt(i);
		if (!isSubconfigValid(pFilterConfig, std::string("Filter")))return false;

		std::optional<int> FilterID = pFilterConfig->getAttribute<int>("FilterID");
		_ASSERTE(FilterID.has_value());
		std::optional<std::string> Sig = pFilterConfig->getAttribute<std::string>("Sig");
		_ASSERTE(Sig.has_value());
		std::optional<int> WorkThreadID = pFilterConfig->getAttribute<int>("WorkThreadID");
		_ASSERTE(WorkThreadID.has_value());
		std::optional<std::string> Connections = pFilterConfig->getAttribute<std::string>("Connections");
		_ASSERTE(Connections.has_value());
		std::stringstream Ss;
		Ss << Connections.value();
		std::vector<Eigen::Vector2i> ConnectionsVec;
		char Left = 0;
		Ss >> Left;
		while (Left == '(')
		{
			char Right, Comma;
			Eigen::Vector2i TempConnection;
			Ss >> TempConnection.x() >> Comma >> TempConnection.y() >> Right;
			if (Comma != ',' || Right != ')')return false;
			ConnectionsVec.emplace_back(TempConnection);
			Left = 0;
			Ss >> Left;
		}

		SFilter TempFilter{ FilterID.value(),Sig.value(),WorkThreadID.value(),ConnectionsVec };
		m_FilterSet.emplace_back(TempFilter);
	}

	const hiveConfig::CHiveConfig* pPipesConfig = pConfig->getSubconfigAt(1);
	if (!isSubconfigValid(pPipesConfig, std::string("Pipes")))return false;
	for (int i = 0; i < pPipesConfig->getNumSubconfigs(); i++)
	{
		const hiveConfig::CHiveConfig* pPipeConfig = pPipesConfig->getSubconfigAt(i);
		if (!isSubconfigValid(pPipeConfig, std::string("Pipe")))return false;

		std::optional<std::string> Sig = pPipeConfig->getAttribute<std::string>("Sig");
		_ASSERTE(Sig.has_value());
		std::optional<int> WorkThreadID = pPipeConfig->getAttribute<int>("WorkThreadID");
		_ASSERTE(WorkThreadID.has_value());
		std::optional<int> SrcFilter = pPipeConfig->getAttribute<int>("SrcFilter");
		_ASSERTE(SrcFilter.has_value());
		std::optional<int> SrcFilterBufferID = pPipeConfig->getAttribute<int>("SrcFilterBufferID");
		_ASSERTE(SrcFilterBufferID.has_value());
		std::optional<int> DstFilter = pPipeConfig->getAttribute<int>("DstFilter");
		_ASSERTE(DstFilter.has_value());
		std::optional<int> DstFilterBufferID = pPipeConfig->getAttribute<int>("DstFilterBufferID");
		_ASSERTE(DstFilterBufferID.has_value());

		SPipe TempPipe{ Sig.value(),WorkThreadID.value(),SrcFilter.value(),SrcFilterBufferID.value(),DstFilter.value(),DstFilterBufferID.value() };
		m_PipeSet.emplace_back(TempPipe);
	}
	
	m_IsReady = true;
	return true;
}

void CFilterPipeConfig::__defineAttributesV()
{
	_defineAttribute(std::string("FilterPipeSystem"), hiveConfig::EConfigDataType::ATTRIBUTE_SUBCONFIG);
	_defineAttribute(std::string("Filters"), hiveConfig::EConfigDataType::ATTRIBUTE_SUBCONFIG);
	_defineAttribute(std::string("Filter"), hiveConfig::EConfigDataType::ATTRIBUTE_SUBCONFIG);
	_defineAttribute(std::string("FilterID"), hiveConfig::EConfigDataType::ATTRIBUTE_INT);
	_defineAttribute(std::string("Sig"), hiveConfig::EConfigDataType::ATTRIBUTE_STRING);
	_defineAttribute(std::string("WorkThreadID"), hiveConfig::EConfigDataType::ATTRIBUTE_INT);
	_defineAttribute(std::string("Connections"), hiveConfig::EConfigDataType::ATTRIBUTE_STRING);
	_defineAttribute(std::string("Pipes"), hiveConfig::EConfigDataType::ATTRIBUTE_SUBCONFIG);
	_defineAttribute(std::string("Pipe"), hiveConfig::EConfigDataType::ATTRIBUTE_SUBCONFIG);
	_defineAttribute(std::string("SrcFilter"), hiveConfig::EConfigDataType::ATTRIBUTE_INT);
	_defineAttribute(std::string("SrcFilterBufferID"), hiveConfig::EConfigDataType::ATTRIBUTE_INT);
	_defineAttribute(std::string("DstFilter"), hiveConfig::EConfigDataType::ATTRIBUTE_INT);
	_defineAttribute(std::string("DstFilterBufferID"), hiveConfig::EConfigDataType::ATTRIBUTE_INT);
}